# coding:utf-8
import os
import sys
import logging
import argparse
import re
import json
import time
from pathlib import Path
import base64
from enum import Enum, unique
import requests
from flask import Flask
from flask import request
from flask import jsonify, make_response
from flask_cors import CORS
from MainFile import pred

# docker data root and host root
ais_version = '1.2.7'
docker_data_root = '/usr/local/data/DR/AIS'
host_data_root = '/home/cao/data/dicom/AIS'
image_url_prefix = 'http://192.168.30.30:8088/file/download/'
server_name = 'DR_AIS_CLASS'
debug_flag = True
logger = None
port_number = 5081


def parse_args():
    global server_name, debug_flag, docker_data_root, host_data_root, deploy_config_file, image_url_prefix, port_number
    parser = argparse.ArgumentParser(description="AIS DR Classification Service!")
    parser.add_argument('--server_name', type=str, default='DR_AIS_CLASS')
    parser.add_argument('--debug_flag', default=False)
    parser.add_argument('--logger', default=None)
    parser.add_argument('--port_number', type=int, default=5081)
    parser.add_argument('--docker_data_root', type=str, default='/usr/local/data/DR/AIS')
    parser.add_argument('--host_data_root', type=str, default='/home/cao/data/dicom/AIS')
    parser.add_argument('--image_url_prefix', type=str, default='http://192.168.30.30:8088/file/download/')
    args = parser.parse_args()
    return args

@unique
class HTTPResCode(Enum):
    Failed = 0
    Interface_success = 1000
    Interface_auth_failed = 1001
    License_expired = 1002
    Miss_parameter = 1003
    Serices_uncompleted = 1004
    Image_modality = 1005
    Serices_empty = 1006

@unique
class ScannerType(Enum):
    X_ray = 1
    CT=2

@unique
class UploadStatus(Enum):
    Faile = 0
    Success = 1

@unique
class StoreType(Enum):
    Local = 0
    Base64 = 1
    URL = 2

@unique
class DRDirection(Enum):
    AP = 0
    LAT = 1
    Lbend = 2
    Rbend = 3
    Unknown = 4

@unique
class ImageFileType(Enum):
    JPG = 0
    DICOM = 1


def is_docker():
    path = "/proc/" + str(os.getpid()) + "/cgroup"
    if not os.path.isfile(path): return False
    with open(path) as f:
        for line in f:
            if re.match("\d+:[\w=]+:/docker(-[ce]e)?/\w+", line):
                return True
    return False


def check_save_dir(seriesno)->Path:
    if is_docker():
        # convert docker file path
        save_dir = docker_data_root
    else:
        save_dir = host_data_root

    save_dir = Path(save_dir)
    if not save_dir.exists():
        os.makedirs(str(save_dir))

    save_dir = Path(save_dir).joinpath(seriesno)
    if not save_dir.exists():
        save_dir.mkdir()
    return save_dir


def parsing_ais_data(seriesno, ais_data_list):
    # image_dict = {'ap': ap_file,
    #               'lat': lat_file,
    #               'lbend': lbend_file,
    #               'rbend': rbend_file}
    if ais_data_list:
        save_dir = check_save_dir(seriesno)
        ais_file_dict = {}
        for i, ais_image in enumerate(ais_data_list):
            orientation = str(ais_image.get('orientation', DRDirection.Unknown.name)).lower()
            if ais_image['storeType'] == StoreType.Local.name:
                ais_file_dict[orientation] =  str(ais_image.get('content', ''))
            elif ais_image['storeType'] == StoreType.Base64.name:
                image_content = ais_image.get('content', '')
                image_bs64_str = image_content.encode('utf-8')
                imgdata = base64.b64decode(image_bs64_str)
                filetype = ais_image.get('fileType', ImageFileType.JPG.name)
                # image_sopNo = ''.join(random.sample(string.ascii_letters + string.digits, 10))
                image_sopNo = orientation
                if filetype == 'JPG':
                    save_name = save_dir.joinpath(image_sopNo + '.jpg')
                elif filetype == 'DICOM':
                    save_name = save_dir.joinpath(image_sopNo + '.dcm')
                with open(str(save_name), "wb") as f:
                    f.write(imgdata)
                ais_file_dict[orientation] = str(save_name)
            elif ais_image['storeType'] == StoreType.URL.name:
                image_content = ais_image.get('content', '')
                image_content = image_url_prefix+str(image_content)
                res = requests.get(str(image_content))
                image_sopNo = orientation
                filetype = ais_image.get('fileType', ImageFileType.JPG.name)
                if filetype == 'JPG':
                    save_name = save_dir.joinpath(image_sopNo + '.jpg')
                elif filetype == 'DICOM':
                    save_name = save_dir.joinpath(image_sopNo + '.dcm')
                with open(str(save_name), "wb") as f:
                    f.write(res.content)
                ais_file_dict[orientation] = str(save_name)
        return ais_file_dict, save_dir


# new flask app
app = Flask(server_name)
app.config['JSON_AS_ASCII'] = False


@app.route('/', methods=['GET', 'POST'])
def version():
    return jsonify({str(server_name) + " version": ais_version})


@app.route('/api/v1/ais/demo-det', methods=['GET', 'POST'])
def test_demo():
    """
    本地测试
    :return:
    """
    result = {}
    result['image_list'] = {}
    result['class_info'] = {}

    case_dir = 'DR_vertebral/test/'
    result['image_list'] = os.listdir(case_dir)
    if len(result['image_list']) > 0:
        result['class_info'] = list(pred(case_dir).astype(float))
        return jsonify(result)  # str(class_info)    #
    else:
        return str('image size is zero')

# @app.route('/api/v1/ais/image-class', methods=['GET', 'POST'])
# def dr_ais_image_class():
#     res: dict = json.loads(request.data)
#     scannerType = res.get('scannerType', 1)
#     seriesNo = res.get('seriesNo', '')
#     status = res.get('status', 0)
#     ais_images = res.get('data', [])
#
#     try:
#         results = {}
#         results['scannerType'] = 1
#         results['seriesNo'] = seriesNo
#         results['ImageClass'] = {}
#         results['code'] = HTTPResCode.Failed.value
#         results['msg'] = ''
#
#         if status != UploadStatus.Success.value:
#             results['code'] = HTTPResCode.Serices_uncompleted.value
#             return jsonify(results)
#
#         if scannerType != ScannerType.X_ray.value:
#             results['code'] = HTTPResCode.Image_modality.value
#             return jsonify(results)
#
#         if not ais_images:
#             results['code'] = HTTPResCode.Serices_empty.value
#             return jsonify(results)
#
#         # 1.create ais images
#         save_dir = None
#         ais_file_dict, save_dir = parsing_ais_data(seriesNo, ais_images)
#
#         # 2.image class
#         logger.info("'/api/v1/ais/image-class' processing.... ais_file_dict: {},  dir: {}".format(str(ais_file_dict), str(save_dir)))
#         image_class = pred(ais_file_dict)
#         results['ImageClass'] = image_class
#
#         results['code'] = HTTPResCode.Interface_success.value
#         logger.info("'/api/v1/ais/image-class' successed! seriesNo: {}, save_dir: {}".format(str(seriesNo), str(save_dir)))
#         return jsonify(results)
#     except Exception as e:
#         logger.error("'/api/v1/ais/image-class' failed! seriesNo: {}, save_dir: {}, error:{}".format(str(seriesNo), str(save_dir), e))
#         return jsonify(results)


@app.route('/api/v1/ais/image_class', methods=['POST'])
def dr_ais_image_class():
    upload_file = request.files['file']
    file_name = upload_file.filename
    try:
        result = {}
        result['imageClass'] = None
        result['code'] = HTTPResCode.Failed.value
        result['msg'] = ''

        image_dir = os.path.join(os.getcwd(), 'download\\')
        upload_file.save(Path(image_dir + file_name))

        # image class
        image_class = pred(image_dir + file_name)
        print(image_class)
        if image_class == 0:
            result['imageClass'] = 'AP'
        elif image_class == 1:
            result['imageClass'] = 'LAT'
        elif image_class == 2:
            result['imageClass'] = 'LBend'
        elif image_class == 3:
            result['imageClass'] = 'RBend'
        result['code'] = HTTPResCode.Interface_success.value
        os.remove(Path(image_dir + file_name))
        return jsonify(result)
    except Exception as e:
        return jsonify(result)


def main():
    # parse args
    parse_args()

    CORS(app, supports_credentials=True)
    if debug_flag:
        app.run(host='192.168.30.200', use_reloader=False, port=port_number, debug=True, processes=1)
    else:
        app.run(host='192.168.30.200', use_reloader=True, port=port_number)


if __name__ == '__main__':
    main()


